package com.osdp.common.sercurity.config;

import com.osdp.common.sercurity.filter.TokenVerifyFilter;
import com.osdp.common.sercurity.service.ITokenIdentifyService;
import com.osdp.common.sercurity.service.impl.AuthenticateServiceImpl;
import com.osdp.common.sercurity.service.impl.DefaultAuthenticateService;
import com.osdp.common.sercurity.service.impl.TokenIdentifyServiceImpl;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.util.CollectionUtils;

import java.util.List;

/**
 * 添加token验证Filter
 *
 * WebSecurityConfigurerAdapter是构建SecurityFilterChain的关键，在WebSecurityConfigurerAdapter的init
 * 方法中会创建一个SecurityBuilder<SecurityFilterChain>类型的实例对象【HttpSecurity】并保存到WebSecurity的
 * securityFilterChainBuilders属性中，后续通过SecurityBuilder来完成SecurityFilterChain的创建。
 *
 */
@EnableWebSecurity
@Configurable
@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true)
public class SecurityAutoConfiguration extends WebSecurityConfigurerAdapter {
    /**
     * 需要忽略的验证资源，在配置文件中取得
     */
    @Value("#{'${osdp.ignore.patterns}'.split(',')}")
    private List<String> ignores;

    @Override
    public void configure(WebSecurity web) throws Exception {
        WebSecurity.IgnoredRequestConfigurer ignoring = web.ignoring();
        if(!CollectionUtils.isEmpty(ignores)){
            ignores.forEach(ignoring::antMatchers);
        }
    }

    /**
     * 添加token验证Filter
     * @param http
     * @throws Exception
     */
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.cors();
        http.headers().frameOptions().disable();
        http.addFilter(new TokenVerifyFilter(super.authenticationManager(),tokenIdentifyService(),authenticateService()));
    }

    @Bean
    public DefaultAuthenticateService authenticateService(){
        return new AuthenticateServiceImpl();
    }

    @Bean
    public ITokenIdentifyService tokenIdentifyService(){
        return new TokenIdentifyServiceImpl();
    }
}
